﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WoChu.WMS.Entity;
using WoChu.WMS.Repository;
using WoChu.Infrastructure.Collection;
using WoChu.Infrastructure.Web;
using System.Web;
using WoChu.Infrastructure.Net;
using WoChu.Infrastructure.EnumType;
using WoChu.Infrastructure.Video;
using WoChu.Infrastructure.Log;
using System.IO;
using WoChu.Infrastructure.Error;
using WoChu.Infrastructure.CacheBase;

namespace Business.Service
{
    /// <summary>
    /// 视频相关服务
    /// </summary>
    public class VideoService
    {
        public SaleAPPVideoRepository _SaleAPPVideoRepository = new SaleAPPVideoRepository();

        public int Save(SaleAPPVideo entity)
        {
            if (entity.ID > 0)
                return _SaleAPPVideoRepository.Update(entity);

            int id = _SaleAPPVideoRepository.Exists(entity);
            int ret = 0;
            if (id == 0)
                ret = _SaleAPPVideoRepository.Add(entity);
            else
            {
                entity.ID = id;
                ret = _SaleAPPVideoRepository.Update(entity);
            }

            return ret;
        }

        public int Delete(SaleAPPVideo entity)
        {
            return _SaleAPPVideoRepository.Delete(entity);
        }
        public List<SaleAPPVideo> GetCheckVideoList(SaleAPPVideo condition)
        {
            var vlist = _SaleAPPVideoRepository.GetVideoList(condition);
            var savePath = ConfigSetting.GetConfigValueByName<string>("Video.SavePath");
            savePath = DirectoryHelper.GetDirNoCreate(savePath);
            var showList = EnumHelper.GetValues(typeof(DurationType));
            var list = vlist.Where(s => showList.Count(l => l == s.DURATION) > 0);   //过略非枚举定义
            var fileList = list.Select(s => new { ID = s.ID, Exists = FileHelper.Exists(DirectoryHelper.PathCombine(savePath, s.FILENAME)) })
                .Where(s => !s.Exists);
            if (fileList.Count() > 0)  //若有文件不存在，则id重置成0
                list.Where(s => fileList.Count(f => f.ID == s.ID) > 0).Foreach((s) => { s.ID = 0; });
            //若是审核，且记录小于DurationType的个数
            if (condition.TYPE == (int)VideoType.审核 && list.Count() != EnumHelper.EnumCount(typeof(DurationType)))
            {
                var ex = list.Select(s => s.DURATION);
                var add = showList.Except(ex).
                    Select(s => new SaleAPPVideo()
                    {
                        DURATION = s,
                        SHEETID = condition.SHEETID,
                        TYPE = condition.TYPE,
                        SUBTYPE = condition.SUBTYPE,
                        FILENAME = VideoCheck.GetVideoPath(condition.StartDate, condition.EndDate, condition.CheckLocation)
                    });
                list = list.Union(add);
            }
            list.Foreach(s => s.State = GetState(s));
            list = list.OrderBy(s => s.DURATION);
            return list.ToList();
        }

        VideoState GetState(SaleAPPVideo video)
        {
            if (video.ID > 0)
                return VideoState.完成;

            //ICacheManage cache = CacheFactory.Create();
            if (_cache.Get<string>(video.FILENAME) == "1")
                return VideoState.下载中;

            return VideoState.未下载;
        }

        ICacheManage _cache = CacheFactory.Create();

        public void CreateVideo(SaleAPPVideo entity, ILog log)
        {
            int backMin = ConfigSetting.GetConfigValueByName<int>("Video.CheckBackMin");
            entity.StartDate = entity.EndDate.AddSeconds(-entity.DURATION);   //负数
            entity.EndDate = entity.EndDate.AddMinutes(backMin);   //之后添加N分钟
            
            int id = _SaleAPPVideoRepository.Exists(entity);
            string checkLocation = entity.CheckLocation;
            DateTime startDate = entity.StartDate;
            DateTime endDate = entity.EndDate;
            string videoPath = VideoCheck.GetVideoPath(startDate, endDate, checkLocation);
            entity.FILENAME = Path.GetFileName(videoPath);
            var state = GetState(entity);
            if (state == VideoState.下载中)
                throw new BussinessException("视频正在生成，请稍后", 1);
            if (id > 0 && FileHelper.Exists(videoPath))
                throw new BussinessException("视频已经生成，请点播放", 1);

            log.LogInfo("开始生成视频", string.Format("时间：{0}-{1} 审核位：{2}", entity.StartDate, entity.EndDate,entity.CheckLocation));
            var dir = HttpContext.Current.Server.MapPath("~/VideoUntity/bin/");
            string exePath = dir + @"VideoUntity.exe";
            string strStartDate = entity.StartDate.ToString("yyyy-MM-dd HH:mm:ss").Replace(" ", "_");
            string strEndDate = entity.EndDate.ToString("yyyy-MM-dd HH:mm:ss").Replace(" ", "_");
            //参数格式：A1 2016-7-7_0:30:0 2016-7-7_0:31:0
            string args = string.Format("{0} {1} {2}", checkLocation, strStartDate, strEndDate);
            try
            {
                _cache.Set(entity.FILENAME, 1, DateTime.Now.AddMinutes(10));
                ProcessHelper.Excute(exePath, args, log);

                if (!FileHelper.Exists(videoPath))
                    throw new BussinessException("视频服务器端没有保存(一般保存5天左右)");

                entity.CREATETIME = DateTime.Now;
                if (id > 0)
                    entity.ID = id;
                int ret = Save(entity);
                _cache.Remove<string>(entity.FILENAME);
            }
            catch (Exception ex)
            {
                _cache.Remove<string>(entity.FILENAME);
                throw ex;
            }

            CheckAndRemoveVideo(log);
        }

        public void CheckAndRemoveVideo(ILog log)
        {
            string driver = HttpContext.Current.Server.MapPath("~").Substring(0, 1); //当前应用的驱动名字
            var max = ConfigSetting.GetConfigValueByName<long>("Video.DriveMaxSize");
            var usedSize = DriverHelper.GetUsedSize(driver);
            if (usedSize > max)
            {
                float deleteSize = (usedSize - max) * 1024;   //M单位
                log.LogWan("硬盘空间超过上限", string.Format("现在使用：{0}G 上限：{1}G", usedSize, max));
                var savePath = ConfigSetting.GetConfigValueByName<string>("Video.SavePath");
                savePath = DirectoryHelper.GetDirNoCreate(savePath);
                DirectoryInfo dir = new DirectoryInfo(savePath);
                var list = dir.GetFiles("*.mp4").Where(s => s.Name.IndexOf("_src") < 0).OrderBy(s => s.CreationTime);

                for (int i = 0; i < list.Count(); i++)
                {
                    var file = list.ElementAt(i);
                    float fileSize = FileHelper.GetFileSize(file);
                    deleteSize = deleteSize - fileSize;
                    FileHelper.Delete(file.FullName);
                    log.LogWan("删除最早文件", string.Format("文件：{0} 大小：{1}M", file.FullName, fileSize));
                    if (deleteSize <= 0)
                        break;
                }
            }
        }
    }
}
